from django.http.response import JsonResponse, HttpResponse
from django.shortcuts import render
from rest_framework.generics import ListAPIView
from apps.oaauth.models import OADepartment, UserStatusChoices
from apps.oaauth.serializers import DepartmentSerializer, UserSerializer
from rest_framework.views import APIView
from .serializers import AddStaffSerializer, ActiveStaffSerializer, StaffUploadSerializer
from rest_framework.response import Response
from rest_framework import status, generics, exceptions, viewsets, mixins
from django.contrib.auth import get_user_model
from django.conf import settings
from utils import aeser
from django.urls import reverse
from OA.celery import debug_task
from .works import send_mail_task
from django.views import View
from urllib import parse
from .paginations import StaffListPagination
from datetime import datetime
import json
import pandas as pd
from django.db import transaction

OAUser = get_user_model()
aes = aeser.AESCipher(settings.SECRET_KEY)


# Create your views here.

def send_active_email(request, email):
    token = aes.encrypt(email)
    active_path = reverse('staff:active_view') + '?' + parse.urlencode({'token': token})
    active_url = request.build_absolute_uri(active_path)
    subject = f'账号激活'
    message = f'请点击以下链接激活账号：{active_url}'
    # send_mail(subject, recipient_list=[email], message=message, from_email=settings.DEFAULT_FROM_EMAIL)
    send_mail_task.delay(email, subject, message)


class DepartmentList(ListAPIView):
    queryset = OADepartment.objects.all()
    serializer_class = DepartmentSerializer


class ActiveStaffView(View):
    def get(self, request):
        token = request.GET.get('token')
        response = render(request, 'active.html')
        response.set_cookie('token', token)
        return response

    def post(self, request):
        try:
            token = request.COOKIES.get('token')
            email = aes.decrypt(token)
            serializer = ActiveStaffSerializer(data=request.POST)
            if serializer.is_valid():
                form_email = serializer.validated_data.get('email')
                user = serializer.validated_data.get('user')
                if email != form_email:
                    return JsonResponse({"code": 400, "message": "邮箱错误！"})
                user.status = UserStatusChoices.ACTIVED
                user.save()
                return JsonResponse({"code": 200, "message": ""})
            else:
                detail = list(serializer.errors.values())[0][0]
                return JsonResponse({'code': 400, 'message': detail})
        except Exception as e:
            return JsonResponse({"code": 400, "message": "token错误"})


class StaffViewSet(
    viewsets.GenericViewSet,
    mixins.ListModelMixin,
    mixins.CreateModelMixin,
    mixins.UpdateModelMixin, ):
    pagination_class = StaffListPagination
    queryset = OAUser.objects.all()

    def get_serializer_class(self):
        if self.request.method in ['GET', 'PUT']:
            return UserSerializer
        else:
            return AddStaffSerializer

    def get_queryset(self):
        # print( self.request.query_params )
        department_id = self.request.query_params.get('department_id')
        realname = self.request.query_params.get('realname')
        date_joined = self.request.query_params.getlist('date_joined[]')

        queryset = self.queryset
        user = self.request.user
        if user.department.name != '董事会':
            if user.department.name != user.department.leader.uid:
                raise exceptions.PermissionDenied
            else:
                queryset = queryset.filter(department=user.department)
        else:
            if department_id:
                queryset = queryset.filter(department_id=department_id)
        if realname:
            queryset = queryset.filter(realname=realname)
        if date_joined:
            try:
                start_time = datetime.strptime(date_joined[0], '%Y-%m-%d')
                end_time = datetime.strptime(date_joined[-1], '%Y-%m-%d')
                queryset = queryset.filter(date_joined__range=(start_time, end_time))
            except ValueError:
                pass

        return queryset.order_by('-date_joined').all()

    def create(self, request, *args, **kwargs):
        serializer = AddStaffSerializer(data=request.data, context={'request': request})
        if serializer.is_valid():
            realname = serializer.validated_data['realname']
            email = serializer.validated_data['email']
            password = serializer.validated_data['password']

            user = OAUser.objects.create_user(email=email, realname=realname, password=password)
            user.department = request.user.department
            user.save()

            send_active_email(request, email)
            return Response()
        else:
            return Response(data={'detail': list(serializer.errors.values())[0][0]}, status=status.HTTP_400_BAD_REQUEST)

    def update(self, request, *args, **kwargs):
        kwargs['partial'] = True
        return super().update(request, *args, **kwargs)


class StaffDownloadView(APIView):
    def get(self, request):
        pks = request.query_params.get('pks')
        try:
            pks = json.loads(pks)
        except Exception:
            return Response({'detail': "员工列表下载错误！"}, status=status.HTTP_400_BAD_REQUEST)
        try:
            current_user = request.user
            queryset = OAUser.objects
            if current_user.department.name != '董事会':
                if current_user.department.leader_id != current_user.uid:
                    return Response({'detail': '您无权限下载数据！'}, status=status.HTTP_403_FORBIDDEN)
                else:
                    queryset = queryset.filter(department_id=current_user.department.id)
            queryset = queryset.filter(pk__in=pks)
            result = queryset.values('realname', 'email', 'department__name', 'date_joined', 'status')
            staff_df = pd.DataFrame(list(result))
            staff_df = staff_df.rename(columns={
                'realname': '姓名',
                'email': '邮箱',
                'department__name': '部门',
                'date_joined': '入职时间',
                'status': '状态'
            })
            response = HttpResponse(content_type='application/xlsx')
            response['Content-Disposition'] = 'attachment; filename="员工信息.xlsx"'
            with pd.ExcelWriter(response) as writer:
                staff_df.to_excel(writer, sheet_name='员工信息')
            return response
        except Exception as e:
            print(e)
            return Response()


class StaffUploadView(APIView):
    def post(self, request):
        serializer = StaffUploadSerializer(data=request.data)
        if serializer.is_valid():
            file = serializer.validated_data.get('file')
            current_user = request.user
            if current_user.department.name != '董事会' or current_user.department.leader_id != current_user.uid:
                return Response({'detail': '您没有权限访问'}, status=status.HTTP_403_FORBIDDEN)
            try:
                staff_df = pd.read_excel(file)
            except Exception as e:
                staff_df = pd.read_excel(file)
            users = []
            for index, row in staff_df.iterrows():
                if current_user.department.name != '董事会':
                    department = current_user.department
                else:
                    try:
                        department = OADepartment.objects.filter(name=row['部门']).first()
                        if not department:
                            return Response({'detail': f'row["部门"]不存在！'}, status=status.HTTP_400_BAD_REQUEST)
                    except OADepartment.DoesNotExist:
                        return Response({'detail': '部门列不存在'}, status=status.HTTP_400_BAD_REQUEST)
                    try:
                        email = row['邮箱']
                        realname = row['姓名']
                        password = '123456'
                        user = OAUser(email=email, realname=realname, department=department,
                                      status=UserStatusChoices.UNACTIVE)
                        user.set_password(password)
                        users.append(user)
                    except Exception as e:
                        return Response({'detail': '文件中数据异常!'}, status=status.HTTP_400_BAD_REQUEST)

            try:
                # 原子操作 （事务操作）
                with transaction.atomic():
                    OAUser.objects.bulk_create(users)
            except Exception as e:
                return Response({'detail': '文件中数据异常!'}, status=status.HTTP_400_BAD_REQUEST)

            for user in users:
                send_active_email(request, user.email)
            return Response()
        else:
            return Response({'detail': list(serializer.errors.values())[0][0]}, status=status.HTTP_400_BAD_REQUEST)


class TestCelery(APIView):
    def get(self, request):
        debug_task.delay()
        return Response({'detail': 'ok'})
